//
// (C) Copyright 2009 Irantha Suwandarathna (irantha@gmail.com)
// All rights reserved.
//

/* Copyright (c) 2001-2008, The HSQL Development Group
 * All rights reserved.
 *
 * Redistribution and use _in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 *
 * Redistributions _in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer _in the documentation
 * and/or other materials provided with the distribution.
 *
 * Neither the name of the HSQL Development Group nor the names of its
 * contributors may be used to endorse or promote products derived from this
 * software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */


using System;
using System.Text;
using System.Collections.Generic;

namespace EffiProz.Core.Lib
{

    /** Provides a collection of convenience methods for processing and
     * creating objects with <code>String</code> value components.
     *
     * @author fredt@users
     * @author boucherb@users
     * @version 1.7.2
     * @since 1.7.0
     */
    public class StringUtil
    {

        /**
         * Returns a string with non alphanumeric chars converted to the
         * substitute character. A digit first character is also converted.
         * By sqlbob@users
         * @param source string to convert
         * @param substitute character to use
         * @return converted string
         */
        public static string toLowerSubset(string source, char substitute)
        {

            int len = source.Length;
            StringBuilder src = new StringBuilder(len);
            char ch;

            for (int i = 0; i < len; i++)
            {
                ch = source[(i)];

                if (!Char.IsLetterOrDigit(ch))
                {
                    src.Append(substitute);
                }
                else if ((i == 0) && Char.IsDigit(ch))
                {
                    src.Append(substitute);
                }
                else
                {
                    src.Append(Char.ToLower(ch));
                }
            }

            return src.ToString();
        }

        /**
    * Builds a bracketed CSV list from the array
    * @param array an array of Objects
    * @return string
    */
        public static String arrayToString(Object array)
        {

            int len = ((Array)array).Length;
            int last = len - 1;
            StringBuilder sb = new StringBuilder(2 * (len + 1));

            sb.Append('{');

            for (int i = 0; i < len; i++)
            {
                sb.Append(((Array)array).GetValue(i));

                if (i != last)
                {
                    sb.Append(',');
                }
            }

            sb.Append('}');

            return sb.ToString();
        }

        ///**
        // * Builds a bracketed CSV list from the array
        // * @param array an array of Objects
        // * @return string
        // */
        //public static string arrayToString(Object array)
        //{

        //    int len = ((Array)array).Length;
        //    int last = len - 1;
        //    StringBuilder sb = new StringBuilder(2 * (len + 1));

        //    sb.Append('{');

        //    for (int i = 0; i < len; i++)
        //    {
        //        sb.Append(((char[])array)[i]);

        //        if (i != last)
        //        {
        //            sb.Append(',');
        //        }
        //    }

        //    sb.Append('}');

        //    return sb.ToString();
        //}

        /**
         * Builds a CSV list from the specified String[], separator string and
         * quote string. <p>
         *
         * <ul>
         * <li>All arguments are assumed to be non-null.
         * <li>Separates each list element with the value of the
         * <code>separator</code> argument.
         * <li>Prepends and appends each element with the value of the
         *     <code>quote</code> argument.
         * <li> No attempt is made to escape the quote character sequence if it is
         *      found public to a list element.
         * <ul>
         * @return a CSV list
         * @param separator the <code>String</code> to use as the list element separator
         * @param quote the <code>String</code> with which to quote the list elements
         * @param s array of <code>String</code> objects
         */
        public static string getList(String[] s, string separator, string quote)
        {

            int len = s.Length;
            StringBuilder b = new StringBuilder(len * 16);

            for (int i = 0; i < len; i++)
            {
                b.Append(quote);
                b.Append(s[i]);
                b.Append(quote);

                if (i + 1 < len)
                {
                    b.Append(separator);
                }
            }

            return b.ToString();
        }

        //public static string getList(Object[] s, string separator, string quote)
        //{

        //    int len = s.Length;
        //    StringBuilder b = new StringBuilder(len * 16);

        //    for (int i = 0; i < len; i++)
        //    {
        //        b.Append(quote);
        //        b.Append(s[i]);
        //        b.Append(quote);

        //        if (i + 1 < len)
        //        {
        //            b.Append(separator);
        //        }
        //    }

        //    return b.ToString();
        //}

        /**
         * Builds a CSV list from the specified int[], <code>separator</code>
         * <code>String</code> and <code>quote</code> <code>String</code>. <p>
         *
         * <ul>
         * <li>All arguments are assumed to be non-null.
         * <li>Separates each list element with the value of the
         * <code>separator</code> argument.
         * <li>Prepends and appends each element with the value of the
         *     <code>quote</code> argument.
         * <ul>
         * @return a CSV list
         * @param s the array of int values
         * @param separator the <code>String</code> to use as the separator
         * @param quote the <code>String</code> with which to quote the list elements
         */
        public static string getList(int[] s, string separator, string quote)
        {

            int len = s.Length;
            StringBuilder b = new StringBuilder(len * 8);

            for (int i = 0; i < len; i++)
            {
                b.Append(quote);
                b.Append(s[i]);
                b.Append(quote);

                if (i + 1 < len)
                {
                    b.Append(separator);
                }
            }

            return b.ToString();
        }


        /**
    * Returns the size of substring that does not contain any trailing spaces
    * @param s the string
    * @return trimmed size
    */
        public static int rightTrimSize(String s)
        {

            int i = s.Length;

            while (i > 0)
            {
                i--;

                if (s[i] != ' ')
                {
                    return i + 1;
                }
            }

            return 0;
        }

        ///**
        // * Builds a CSV list from the specified String[][], separator string and
        // * quote string. <p>
        // *
        // * <ul>
        // * <li>All arguments are assumed to be non-null.
        // * <li>Uses only the first element _in each subarray.
        // * <li>Separates each list element with the value of the
        // * <code>separator</code> argument.
        // * <li>Prepends and appends each element with the value of the
        // *     <code>quote</code> argument.
        // * <li> No attempt is made to escape the quote character sequence if it is
        // *      found public to a list element.
        // * <ul>
        // * @return a CSV list
        // * @param separator the <code>String</code> to use as the list element separator
        // * @param quote the <code>String</code> with which to quote the list elements
        // * @param s the array of <code>String</code> array objects
        // */
        //public static string getList(String[][] s, string separator,
        //                             string quote)
        //{

        //    int len = s.Length;
        //    StringBuilder b = new StringBuilder(len * 16);

        //    for (int i = 0; i < len; i++)
        //    {
        //        b.Append(quote);
        //        b.Append(s[i][0]);
        //        b.Append(quote);

        //        if (i + 1 < len)
        //        {
        //            b.Append(separator);
        //        }
        //    }

        //    return b.ToString();
        //}

        ///**
        // * Appends a pair of string to the string buffer, using the separator between
        // * and terminator at the end
        // * @param b the buffer
        // * @param s1 first string
        // * @param s2 second string
        // * @param separator separator string
        // * @param terminator terminator string
        // */
        //public static void appendPair(StringBuilder b, string s1, string s2,
        //                              string separator, string terminator)
        //{

        //    b.Append(s1);
        //    b.Append(separator);
        //    b.Append(s2);
        //    b.Append(terminator);
        //}

        ///**
        // * Checks if text is empty (characters <= space)
        // * @author: Nitin Chauhan
        // * @return bool true if text is null or empty, false otherwise
        // * @param s string
        // */
        //public static bool isEmpty(string s)
        //{

        //    int i = s == null ? 0
        //                      : s.Length;

        //    while (i > 0)
        //    {
        //        if (s[(--i)] > ' ')
        //        {
        //            return false;
        //        }
        //    }

        //    return true;
        //}

        /**
         * Returns the size of substring that does not contain ane trailing spaces
         * @param s the string
         * @return trimmed size
         */
        public static int rTrimSize(string s)
        {

            int i = s.Length;

            while (i > 0)
            {
                i--;

                if (s[(i)] != ' ')
                {
                    return i + 1;
                }
            }

            return 0;
        }

        /**
         * Skips any spaces at or after start and returns the index of first
         * non-space character;
         * @param s the string
         * @param start index to start
         * @return index of first non-space
         */
        public static int skipSpaces(string s, int start)
        {

            int limit = s.Length;
            int i = start;

            for (; i < limit; i++)
            {
                if (s[(i)] != ' ')
                {
                    break;
                }
            }

            return i;
        }

        /**
         * Splits the string into an array, using the separator. If separator is
         * not found _in the string, the whole string is returned _in the array.
         *
         * @param s the string
         * @param separator the separator
         * @return array of strings
         */
        public static String[] split(string s, string separator)
        {

            List<string> list = new List<string>();
            int currindex = 0;

            for (bool more = true; more; )
            {
                int nextindex = s.IndexOf(separator, currindex);

                if (nextindex == -1)
                {
                    nextindex = s.Length;
                    more = false;
                }

                list.Add(s.Substring(currindex, nextindex - (currindex)));

                currindex = nextindex + separator.Length;
            }

            return (String[])list.ToArray();
        }

        public static String toPaddedString(String source, int length, char pad,
                                        bool trailing)
        {

            int len = source.Length;

            if (len >= length)
            {
                return source;
            }

            StringBuilder sb = new StringBuilder(length);

            if (trailing)
            {
                sb.Append(source);
            }

            for (int i = len; i < length; i++)
            {
                sb.Append(pad);
            }

            if (!trailing)
            {
                sb.Append(source);
            }

            return sb.ToString();
        }

    /**
     * If necessary, adds zeros to the beginning of a value so that the total
     * length matches the given precision, otherwise trims the right digits.
     * Then if maxSize is smaller than precision, trims the right digits to
     * maxSize. Negative values are treated as positive
     */
        public static String toZeroPaddedString(long value, int precision,
                int maxSize)
        {

            StringBuilder sb = new StringBuilder();

            if (value < 0)
            {
                value = -value;
            }

            String s = value.ToString();

            if (s.Length > precision)
            {
                s = s.Substring(precision);
            }

            for (int i = s.Length; i < precision; i++)
            {
                sb.Append('0');
            }

            sb.Append(s);

            if (maxSize < precision)
            {
                sb.Length = maxSize;
            }

            return sb.ToString();
        }

    }
}
